<!DOCTYPE html>
<meta charset="utf-8">
<style>

.link {
  stroke: #ccc;
  stroke-width: 1px;
}

.node {
  fill: #000;
  stroke: #fff;

}
.node {
   stroke: #fff;
  stroke-width: 2px;
}

</style>
<body>
<svg width="100%" height="1200px"></svg>
<script src="d3.v3.min.js"></script>
<script type="text/javascript" src="z_2.js"></script>
<!-- <script src="./d3.v4.min.js"></script> -->
<script>
var nodes = [];
var links = [];
var ss =test()
links = ss.l;
nodes = ss.n;
var w = 800
var h = 2200

// var root = null;
var color = d3.scale.category20();

var nodes_handle = d3.selectAll("circle");
var links_handle = d3.selectAll("line");



var force = d3.layout.force() // 建立 Layout
  .nodes(nodes)
  .links(links)
  .charge(-200)
  .size([w,h]);            // 設定範圍
  
var zoom = d3.behavior.zoom()
    .scaleExtent([0.1, 10])
    .on("zoom", zoomed);

function zoomed() {
    container
      .attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}



// var nodes_data = force.nodes()
// var links_data = force.links()




var container = d3.select("svg").append("g");
d3.select("svg").call(zoom);
// container.call("zoom", zoom);

function init(){
  var link = container.selectAll("line.line")
    .data(links);
  
  link.exit().remove()
  link.enter()
    .append("line")
    .attr("class",".line")
    .style("stroke","#ccc")
  

  var circles = container
    .selectAll("circle")
    .data(nodes);
  circles.exit().remove();
  
  circles.enter()
    .append("circle")
    .style("fill", function(d){ return color( d.index)})
    .call(force.drag)
    .on("mouseover",function(d, i ){
      indexs = find_nearby(d);
      indexs.push(d.index);
      d3.selectAll("circle")
        .style("fill", function(d ){
          if (indexs.includes(d.index )){
            return "#6798d2";
            // console.log(d.index);
          }else{
            return "#EFEFEF";
          }
        })
    }).on("mouseout",function(d){
      d3.selectAll("circle").style("fill", function(e){ return color(e.index)});
    })
  
  // update()
  return {"links": link, "circles": circles}  
}

function update(){


  link = container.selectAll("line").data(links);
  link.enter().append("line")
    // .attr("class",".line")
  //   .attr("id",function(d){ return d.source.index + "-" + d.target.index})
    .style("stroke","#ccc")
    .attr("id",function(d){ return d.source.index + "-" + d.target.index});
  link.exit().remove()

  // nodes = force.nodes(nodes) ;              // 綁定資料
  // links = force.links(links);
  node = container.selectAll("circle").data(nodes);
  node.enter().append("circle")
  //   .append("circle")
  //   .attr("id",function(d){ return d.index})
    .style("fill", function(d){ return  "#EFEFEF"})//color( d.index)})
    // .call(force.drag)
    .on("mouseover",function(d, i ){
      indexs = find_nearby(d);
      indexs.push(d.index);
      d3.selectAll("circle")
        .style("fill", function(d ){
          if (indexs.includes(d.index )){
            return "#6798d2";
          }else{
            return "#EFEFEF";
          }
        })
        force.linkDistance(70).start();
      
    }).on("mouseout",function(d){
      d3.selectAll("circle").style("fill", function(e){ return color(e.index)});
    }).call(force.drag);

  node.exit().remove();

  // cal()

  function tick() { // tick 會不斷的被呼叫
    link.attr({
      x1 :function(d){ return d.source.x; },
      y1 :function(d){ return d.source.y; },
      x2 :function(d){ return d.target.x; },
      y2 :function(d){ return d.target.y }
    });

    node.attr({
      cx: function(it) { return it.x; },  // it.x 由 Force Layout 提供
      cy: function(it) { return it.y; },  // it.y 由 Force Layout 提供
      r: 5,
    }); 
  }

  force.on("tick", tick)           // 設定 tick 函式   
    .linkDistance(20)
    .start(); 
}


// nodes_handle = data.circles;
// links_handle = data.links;

function get_nearby_nodes(raw,i){
  node = i;
  ls = []
  raw.forEach(
    function(d){
      if (d.source == node){
        ls.push(d.target);
      }
  })
  return ls;
}


function remove_node(inx){
  node = find_node(inx);
  nodes.pop(node);
  ls =  find_links(node);
  ls.forEach(function(d){
    links.pop(d);
  })
  update();
}


// function cal(){
//   links.forEach(function(d){
//     tmp = get_nearby_nodes(links,d.target).length
//     // console.log(tmp, d.target);
//     d.value = 30 + 1 *tmp;
//   });
  
// }

function find_nearby(node){
  inx = node.index;
  links = force.links()
  indexs = []
  links.forEach(function(d){
    if (d.source.index == inx){
      // console.log(d.target.index)
      indexs.push(d.target.index)
    }
  })

  return indexs;
}

function find_node(i){
  var t_node = null
  force.nodes().forEach(function(d){
    if (d.index == i){
      t_node = d;
    }
  })
  return t_node;
}

function find_links(node){
  var l = []
  force.links().forEach(function(D){
    if (D.source == node){
      l.push(D);
    }
    if (D.target == node){
      l.push(D);
    }
  })
  return l;
}


function remove_nodes(inx){
  node = find_node(inx);
  nodes.pop(node);
  ls =  find_links(node);
  ls.forEach(function(d){
    links.pop(d);
    nodes.pop(d.target);
    nodes.pop(d.source);
  })
  update();
}


function add_node(inx,node){
  n = find_node(inx);
  tmp = find_node(node.id);
  if_true = true;

  new_link = { source:n , target:node}
  nodes.push(node);
  links.push(new_link);
  update();
  return if_true;
}


function add_link(s,t){
  s_ndoe = find_node(s);
  t_ndoe = find_node(t);
  new_link = {source:s_ndoe, target: t_ndoe}
  links.push(new_link);
  update();
}

// cal()
// init()
update()

</script>
